Comandos para realizar branching en git.
> git branch <nombre>
> git checkout <nombre branch>
> git branch -vv
> git branch -r -vv
> git branch -a -vv
> git branch -d <nombre branch>
> git branch -D <nombre branch>
La opcion -D permite forzar el borrado en caso de que la rama tenga un merge pendiente
git push <nombre remoto> --delete <nombre rama>
Ejemplo:
git push origin --delete feature/login
En Git por cada rama que creamos realmente existen 3 ramas:
Por ejemplo cuando hacemos un fetch lo que estámos haciendo es sincronizar la rama remota (en el Github por ejemplo) con nuestra rama "espejo" que tenemos en nuestro local (origin/rama), de manera que podemos usar "origin/<nombre_rama>" para ver los cambios que hay en remoto y despues decidir si queremos hacer un merge con nuestra rama local.
En el caso de hacer un pull los cambios se descargan a la rama "espejo" y se mergean directamente con la rama local.
La rama espejo (origin/rama) solo es una rama intermedia para almacenar en local la información que hay en el repositorio remoto.
Para verificar el estado de una rama podemos usar el siguiente comando:
> git status
Para comprobar mas informacion sobre con que rama remota esta vinculada y demas informacion podemos usar:
git remote show origin
Si queremos asegurarnos de que la comparacion se haga con el repositorio remoto actualizado lo haremos de la siguiente manera
> git remote update
> git status
De esta manera nos aseguramos de que la informacion que tenemos del repositorio remoto esta actualizado
git status nos dira:
Cuando hacemos un clone de un repositorio se descarga la rama principal (main) si queremos descargar otra rama podemos hacerlo con el siguiente comando:
> git branch --track <nombrelocal> <origin/nombreremoto>
Este comando crea una rama en nuestro repositorio local y la enlaza (--track) con la rama del repositorio remoto
NOTA: Un fallo que cometia era el de hacer checkout origin/rama para descargar una rama, eso no funciona, ya que lo unico que haces con eso es mover el HEAD a la rama del repositorio remoto y el HEAD queda desacoplado, si despues haces un git branch en ese caso si que se queda enlazada la rama en remoto con la nueva rama que se crea en local, pero no es la manera correcta de hacerlo, para hacerlo con checkout se puede hacer asi:.
> git checkout -t <origin/nombreremoto>
Si queremos subir una rama al repositorio remoto lo hacemos con el siguiente comando:
> git push -u <origin/ramaremota> <ramalocal>
Si lo hacemos sin el parametro -u y la rama no existe en el repositorio remoto, nos dara error, tenemos que usar la opcion -u la cual creara una conexion directa entre la rama local y la remota.
Para mover una rama a un commit anterior lo hacemos con el siguiente comando:
> git branch -f <rama> <Hash del commit>
Tambien podemos mover la rama actual a un estado anterior descartando todos los commits que hemos hecho tal que asi (solo podemos hacerlo en local):
> git reset --hard <Hash del commit>
Para consultar el hash del commit podemos hacer un git log
Si simplemente queremos movernos temporalmente a un commit anterior podemos hacerlo con:
> git checkout <Hash del commit>
para volver al commit mas reciente lo haríamos con el nombre de la rama sin mas:
> git checkout <rama>
Normalmente esto no se debe de hacer ya que la historia de un repositorio siempre tiene que ir hacia delante ya que si no se pueden crear incroguencias en la rama con los demas miembros de un equipo
De todas maneras si se quiere hacer se puede con el siguiente comando:
> git push <nombre remoto> -f <id commit>:<nombre rama>
Ejemplo:
git push origin -f 45be5dc73751774cc303b0c4ae71214699090630:main
La opción -f es necesaria a veces ya que cuando te mueves hacia atras en un commit puede haber incongruencias (de archivos que desaparecen por ejempo) y necesitas forzar el cambio.
Para comparar dos ramas lo hacemos con la opcion diff, ejecutamos el comando de la siguiente manera:
> git diff origin/main main
Con el comando anterior comparamos la rama main del repositorio remoto con la rama main del repositorio local, normalmente es mas comodo indicar primero la rama que en teoria es mas antigua y despues la rama en la que estamos realizando cambios, para que diff nos muestre de manera visualmente mas correcta los cambios realizados (si lo hacemos al reves funciona igual, pero los cambios nuevos apareceran como cambios eliminados en comparacion con la otra rama).
Otra manera de ejecutar el diff es la siguiente:
> git diff <rama>
De esta manera compara la rama que le pasamos con la rama activa actual (el HEAD)
Otra manera es esta:
> git diff HEAD^
En este comando compara un commit por encima del HEAD con la rama actual
Para unir dos ramas usamos la opcion merge, primero tenemos que ponernos en la rama en la que queremos insertar todos los cambios y despues indicar la rama de la que queremos realizar la insercion.
(podemos decir que el merge se hace hacia el HEAD y no desde el HEAD)
Si queremos hacer un merge en la rama main, lo hariamos de la siguiente manera:
> git checkout main
> git merge otraRama
De esta manera introduciriamos todas las modificaciones de la rama otraRama en la rama main
Cuando dos ramas modifican un mismo archivo pueden llegar a una situacion de conflicto, en ese caso al intentar hacer un merge se nos mostrara el siguiente mensaje:
jericho@localhost:~/gittest> git merge ramaTest
Auto-fusionando test.txt
CONFLICTO (contenido): Conflicto de fusión en test.txt
Fusión automática falló; arregle los conflictos y luego realice un commit con el resultado.
En este caso el archivo inicial tenia el siguiente contenido
Contenido inicial
Despues desde la rama main se hizo el siguiente cambio:
Contenido inicial
Modificacion main
Y simultaneamente desde la rama ramaTest se hizo el siguiente cambio:
Contenido inicial
Modificacion ramaTest
Al surgir el conflicto se nos indica que revisemos el archivo que ahora contiene los dos cambios de esta manera:
Contenido inicial
<<<<<<< HEAD
Modificacion main
=======
modificacion ramaTest
>>>>>>> ramaTest
En el archivo que genera el merge se pueden ver cuales son las dos modificaciones que ha hecho cada rama.
Para solucionar el conflicto simplemente editamos dicho archivo de manera manual para dejarlo como queramos (ya sea borrando unas cosas y dejando otras o fusionando el contenido a nuestro gusto), el archivo que guardemos sera el que se guarde de manera definitiva en la rama como resultado final del merge
En este caso yo quiero dejar las dos modificaciones de cada una de las ramas, una despues de otra, asi que simplemente borro los indicadores de las modificaciones de cada rama y dejo el archivo tal que asi:
Contenido inicial
Modificacion main
modificacion ramaTest
Y ahora para dar por finalizado el conflicto hago un commit, de esta manera indico que el archivo es tal cual asi como debe de quedar como resultado final.
> git commit -a -m "Resolucion de conlicto"
Git | Branch